package com.mes.cloud.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mes.cloud.api.dto.request.UpdateEnableRequest;
import com.mes.cloud.api.dto.request.position.PositionUpdateDataAuthRequest;
import com.mes.cloud.api.dto.request.position.SysPositionOrgAuthRequest;
import com.mes.cloud.api.dto.request.position.SysPositionPageRequest;
import com.mes.cloud.api.dto.request.position.SysPositionRequest;
import com.mes.cloud.api.dto.response.organization.SysOrganizationPositionDto;
import com.mes.cloud.api.dto.response.position.SysPositionDetailsDto;
import com.mes.cloud.api.dto.response.position.SysPositionDto;
import com.mes.cloud.api.dto.response.position.SysPositionPageDto;
import com.mes.cloud.exception.BaseException;
import com.mes.cloud.common.CommPager;
import com.mes.cloud.common.JsonResult;
import com.mes.cloud.constant.Constants;
import com.mes.cloud.dao.SysPositionDao;
import com.mes.cloud.dao.SysPositionOrganizationAuthDao;
import com.mes.cloud.entity.SysPosition;
import com.mes.cloud.entity.SysPositionLog;
import com.mes.cloud.entity.SysPositionOrganizationAuth;
import com.mes.cloud.entity.vo.organization.SysOrganizationPositionVo;
import com.mes.cloud.entity.vo.position.SysPositionDetailsVo;
import com.mes.cloud.entity.vo.position.SysPositionPageVo;
import com.mes.cloud.enums.HttpStatusEnum;
import com.mes.cloud.util.DateUtil;
import com.mes.cloud.util.UserUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 岗位表
 *
 * @author xy
 * @version 2019-08-03 08:39:11
 * @email yuan.xue3@pactera.com
 */
@Service
public class SysPositionService {

    private SysPositionDao sysPositionDao;

    private IPKeyGenerator ipKeyGenerator;

    private SysEmployeePositionService sysEmployeePositionService;

    private LogService logService;

    private SysCodeGeneratorService sysCodeGeneratorService;

    private SysPositionOrganizationAuthDao sysPositionOrganizationAuthDao;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    public SysPositionService(SysPositionDao sysPositionDao
            , IPKeyGenerator ipKeyGenerator
            , SysEmployeePositionService sysEmployeePositionService
            , LogService logService
            , SysCodeGeneratorService sysCodeGeneratorService, SysPositionOrganizationAuthDao sysPositionOrganizationAuthDao) {
        this.sysPositionDao = sysPositionDao;
        this.ipKeyGenerator = ipKeyGenerator;
        this.sysEmployeePositionService = sysEmployeePositionService;
        this.logService = logService;
        this.sysCodeGeneratorService = sysCodeGeneratorService;
        this.sysPositionOrganizationAuthDao = sysPositionOrganizationAuthDao;
    }

    /**
     * <分页查列表>
     *
     * @param pageRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult<com.shinho.tntframe.core.common.model.CommPager<com.shinho.crm.base.api.dto.response.position.SysPositionPageDto>>
     * @author xy
     * @date 2019/8/9 10:22
     */
    public JsonResult<CommPager<SysPositionPageDto>> pageList(SysPositionPageRequest pageRequest) {
        Page<SysPositionPageDto> page = PageHelper.startPage(pageRequest.getCurrentPage(), pageRequest.getPageSize());
        //查询条件
        pageRequest.setDelFlag(Constants.DEL_FLAG_NO);
        List<SysPositionPageVo> sysPositionList = sysPositionDao.pageList(pageRequest);
        List<SysPositionPageDto> sysPositionDtoList = new ArrayList<>();
        for (SysPositionPageVo sysOrganizationPositionVo : sysPositionList) {
            SysPositionPageDto sysPositionDto = new SysPositionPageDto();
            BeanUtils.copyProperties(sysOrganizationPositionVo, sysPositionDto);
            sysPositionDtoList.add(sysPositionDto);
        }
        CommPager<SysPositionPageDto> pageResult = new CommPager<>(page, sysPositionDtoList);
        JsonResult<CommPager<SysPositionPageDto>> jsonResult = new JsonResult<>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(pageResult);
        return jsonResult;
    }

    /**
     * <查列表>
     *
     * @param sysPositionRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult<java.util.List<com.shinho.crm.base.api.dto.response.position.SysPositionDto>>
     * @author xy
     * @date 2019/8/9 10:22
     */
    public JsonResult<List<SysPositionDto>> list(SysPositionRequest sysPositionRequest) {
        //查询条件
        SysPosition selectParam = new SysPosition();
        selectParam.setDelFlag(Constants.DEL_FLAG_NO);
        BeanUtils.copyProperties(sysPositionRequest, selectParam);

        List<SysPosition> sysPositionList = sysPositionDao.select(selectParam);
        List<SysPositionDto> sysPositionDtoList = new ArrayList<>();
        for (SysPosition sysPosition : sysPositionList) {
            SysPositionDto sysPositionDto = new SysPositionDto();
            BeanUtils.copyProperties(sysPosition, sysPositionDto);
            sysPositionDtoList.add(sysPositionDto);
        }

        JsonResult<List<SysPositionDto>> jsonResult = new JsonResult<>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(sysPositionDtoList);

        return jsonResult;
    }

    /**
     * <新增>
     *
     * @param sysPositionRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult
     * @author xy
     * @date 2019/8/9 10:22
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult insert(SysPositionRequest sysPositionRequest) {
        //1.检查岗位负责人
        JsonResult jsonResult = new JsonResult();
        //验证是否已选择组织
        if (StringUtils.isEmpty(sysPositionRequest.getOrganizationId())) {
            jsonResult.setMsg(HttpStatusEnum.ORG_NOT_NULL.getMessage())
                    .setCode(HttpStatusEnum.ORG_NOT_NULL.getCode());
            return jsonResult;
        }
        //如果同组织的有重名的岗位，报错：同一组织不允许有重名的岗位
        SysPosition sysPosition = new SysPosition();
        sysPosition.setOrganizationId(sysPositionRequest.getOrganizationId());
        sysPosition.setName(sysPositionRequest.getName());
        int sysPositionCount = sysPositionDao.selectCount(sysPosition);
        if (sysPositionCount > 0) {
            jsonResult.setMsg(HttpStatusEnum.ORG_POSITION_NAME_EXIST.getMessage())
                    .setCode(HttpStatusEnum.ORG_POSITION_NAME_EXIST.getCode());
            return jsonResult;
        }

        String leaderFlag = sysPositionRequest.getOrganizationLeader();
        //如果是设置组织负责人，检查组织是否已经存在组织负责人
        if (Constants.YES.equals(leaderFlag)) {
            sysPosition = new SysPosition();
            sysPosition.setOrganizationLeader(leaderFlag);
            sysPosition.setOrganizationId(sysPositionRequest.getOrganizationId());
            List<SysPosition> list = sysPositionDao.select(sysPosition);
            if (!CollectionUtils.isEmpty(list)) {
                jsonResult.setMsg(HttpStatusEnum.ORG_LEADER_EXIST.getMessage())
                        .setCode(HttpStatusEnum.ORG_LEADER_EXIST.getCode());
                return jsonResult;
            }
        }
        BeanUtils.copyProperties(sysPositionRequest, sysPosition);
        //2.设置编码
        String code = sysCodeGeneratorService.getCode(Constants.CODE_GENERATOR_POSITION);
        sysPosition.setCode(code);
        //3.插入数据
        sysPosition.setId(ipKeyGenerator.getGenerateKey());
        sysPosition.setUpdateDateStr(DateUtil.updateDateStr());
        sysPosition.setCreateBy(UserUtil.getCreateByName());
        sysPosition.setUpdateBy(UserUtil.getUpdateByName());
        sysPosition.setCreateByNo(UserUtil.getCreateByNo());
        sysPosition.setUpdateByNo(UserUtil.getUpdateByNo());
        int count = sysPositionDao.insertSelective(sysPosition);
        if (count > 0) {
            //插入日志
            this.insertLog(sysPosition.getId(), Constants.ADD_POSITION);
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(), HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * <更新>
     *
     * @param sysPositionRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult
     * @author xy
     * @date 2019/8/9 10:23
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult update(SysPositionRequest sysPositionRequest) {
        SysPosition sysPosition = new SysPosition();
        JsonResult jsonResult = new JsonResult();
        //验证是否已选择组织
        if (StringUtils.isEmpty(sysPositionRequest.getOrganizationId())) {
            jsonResult.setMsg(HttpStatusEnum.ORG_NOT_NULL.getMessage())
                    .setCode(HttpStatusEnum.ORG_NOT_NULL.getCode());
            return jsonResult;
        }
        String reqId = sysPositionRequest.getOrganizationId();
        String reqName = sysPositionRequest.getName();

        SysPosition sysPositionRecord = sysPositionDao.selectByPrimaryKey(sysPositionRequest.getId());
        String oId = sysPositionRecord.getOrganizationId();
        String pName = sysPositionRecord.getName();

        if (!reqId.equals(oId) || !reqName.equals(pName)) {
            //如果同组织的有重名的岗位，报错：同一组织不允许有重名的岗位
            SysPosition queryPosition = new SysPosition();
            queryPosition.setOrganizationId(reqId);
            queryPosition.setName(reqName);
            int sysPositionCount = sysPositionDao.selectCount(queryPosition);
            if (sysPositionCount > 0) {
                jsonResult.setMsg(HttpStatusEnum.ORG_POSITION_NAME_EXIST.getMessage())
                        .setCode(HttpStatusEnum.ORG_POSITION_NAME_EXIST.getCode());
                return jsonResult;
            }
        }

        String leaderFlag = sysPositionRequest.getOrganizationLeader();
        //如果是设置组织负责人，检查组织是否已经存在组织负责人
        if (Constants.YES.equals(leaderFlag)) {
            sysPosition.setOrganizationLeader(leaderFlag);
            sysPosition.setOrganizationId(sysPositionRequest.getOrganizationId());
            //根据组织负责人状态，组织id查询
            List<SysPosition> list = sysPositionDao.select(sysPosition);
            if (!CollectionUtils.isEmpty(list)) {
                //检查本次提交的数据是否已经是组织负责人,如果不是提示组织已经存在负责人
                String id = list.get(0).getId();
                if (!sysPositionRequest.getId().equals(id)) {
                    jsonResult.setMsg(HttpStatusEnum.ORG_LEADER_EXIST.getMessage())
                            .setCode(HttpStatusEnum.ORG_LEADER_EXIST.getCode());
                    return jsonResult;
                }
            }
        }

        BeanUtils.copyProperties(sysPositionRequest, sysPosition);
        //更新记录
        sysPosition.setUpdateDateStr(DateUtil.updateDateStr());
        sysPosition.setUpdateBy(UserUtil.getUpdateByName());
        sysPosition.setUpdateByNo(UserUtil.getUpdateByNo());
        int count = sysPositionDao.updateByPrimaryKeySelective(sysPosition);
        if (count > 0) {
            //插入日志
            this.insertLog(sysPosition.getId(), Constants.UPDATE_POSITION);
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(), HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * <查看详情>
     *
     * @param id
     * @return com.shinho.tntframe.core.common.model.JsonResult<com.shinho.crm.base.api.dto.response.position.SysPositionDetailsDto>
     * @author xy
     * @date 2019/8/9 10:23
     */
    @SuppressWarnings("unchecked")
    public JsonResult<SysPositionDetailsDto> get(String id) {
        JsonResult jsonResult = new JsonResult();
        SysPositionDetailsVo sysPositionDetailVo = sysPositionDao.getSysPositionDetail(id);

        if (Objects.isNull(sysPositionDetailVo)) {
            return jsonResult.setCode(HttpStatusEnum.RECORD_NOT_EXIST.getCode())
                    .setMsg(HttpStatusEnum.RECORD_NOT_EXIST.getMessage());
        }

        SysPositionDetailsDto sysPositionDetailDto = new SysPositionDetailsDto();
        BeanUtils.copyProperties(sysPositionDetailVo, sysPositionDetailDto);

        return jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(sysPositionDetailDto);
    }

    /**
     * <禁用启用>
     *
     * @param updateEnableRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult
     * @author xy
     * @date 2019/8/9 10:23
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult updateEnableFlag(UpdateEnableRequest updateEnableRequest) {
        updateEnableRequest.setUpdateDateStr(DateUtil.updateDateStr());
        updateEnableRequest.setUpdateBy(UserUtil.getUpdateByName());
        updateEnableRequest.setUpdateByNo(UserUtil.getUpdateByNo());
        //检查岗位下是否有员工
        JsonResult jsonResult = new JsonResult();
        List<String> ids = updateEnableRequest.getIds();
        String enable = updateEnableRequest.getEnableFlag();
        //如果操作是禁用
        if (Constants.ENABLE_FLAG_NO.equals(enable)) {
            List<String> resultIds = new ArrayList<>();
            if (!CollectionUtils.isEmpty(ids)) {
                for (String id : ids) {
                    //如果数量大于0
                    int size = sysEmployeePositionService.selectCount(id);
                    if (size > 0) {
                        resultIds.add(id);
                    }
                }
            }
            if (resultIds.size() > 0) {
                //返回不能更新数据列表，提示用户
                jsonResult.setMsg(HttpStatusEnum.POSITION_ENABLE_ERROR.getMessage());
                jsonResult.setCode(HttpStatusEnum.POSITION_ENABLE_ERROR.getCode());
                jsonResult.setData(resultIds);
                return jsonResult;
            }
        }
        int count = sysPositionDao.batchUpdateEnable(updateEnableRequest);
        if (count > 0) {
            String flag = Constants.ENABLE_POSITION;
            if (Constants.ENABLE_FLAG_NO.equals(updateEnableRequest.getEnableFlag())) {
                flag = Constants.DISABLE_POSITION;
            }
            // 插入操作日志
            for (String id : updateEnableRequest.getIds()) {
                this.insertLog(id, flag);
            }
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(), HttpStatusEnum.FAIL.getMessage());
        }

        return jsonResult;
    }

    /**
     * <分页查组织岗位列表>
     *
     * @param pageRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult<com.shinho.tntframe.core.common.model.CommPager<com.shinho.crm.base.api.dto.response.organization.SysOrganizationPositionDto>>
     * @author xy
     * @date 2019/8/9 10:24
     */
    public JsonResult<CommPager<SysOrganizationPositionDto>> pageOrganizationPositionList(SysPositionPageRequest pageRequest) {
        Page<SysPositionDto> page = PageHelper.startPage(pageRequest.getCurrentPage(), pageRequest.getPageSize());
        //查询条件
        SysPosition selectParam = new SysPosition();
        BeanUtils.copyProperties(pageRequest, selectParam);

        List<SysOrganizationPositionVo> sysPositionList = sysPositionDao.getSysOrganizationPosition(pageRequest);
        List<SysOrganizationPositionDto> sysPositionDtoList = new ArrayList<>();
        for (SysOrganizationPositionVo sysPosition : sysPositionList) {
            SysOrganizationPositionDto sysPositionDto = new SysOrganizationPositionDto();
            BeanUtils.copyProperties(sysPosition, sysPositionDto);
            sysPositionDtoList.add(sysPositionDto);
        }

        CommPager<SysOrganizationPositionDto> pageResult = new CommPager<>(page, sysPositionDtoList);
        JsonResult<CommPager<SysOrganizationPositionDto>> jsonResult = new JsonResult<>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(pageResult);

        return jsonResult;
    }

    /**
     * <插入日志>
     *
     * @param id, logMessage
     * @author xy
     * @date 2019/8/8 19:25
     */
    @SuppressWarnings("Duplicates")
    private void insertLog(String id, String logMessage) {
        SysPositionLog sysPositionLog = new SysPositionLog();
        sysPositionLog.setPositionId(id);
        sysPositionLog.setMenuCode(Constants.POSITION_MENU_CODE);
        sysPositionLog.setLog(logMessage);
        sysPositionLog.setId(ipKeyGenerator.getGenerateKey());
        sysPositionLog.setUpdateDateStr(DateUtil.updateDateStr());
        sysPositionLog.setCreateBy(UserUtil.getCreateByName());
        sysPositionLog.setUpdateBy(UserUtil.getUpdateByName());
        sysPositionLog.setCreateByNo(UserUtil.getCreateByNo());
        sysPositionLog.setUpdateByNo(UserUtil.getUpdateByNo());
        logService.insertPositionLog(sysPositionLog);
    }

    /**
     * 更新岗位的数据授权
     *
     * @param positionUpdateDataAuthRequest
     * @return
     */
    public JsonResult updatePositionDataAuth(PositionUpdateDataAuthRequest positionUpdateDataAuthRequest) {
        JsonResult jsonResult = new JsonResult();
        Set<String> positionIds = positionUpdateDataAuthRequest.getPositionIds();
        for (String positionId : positionIds) {
            //删除岗位的数据授权
            SysPositionOrgAuthRequest sysPositionOrgAuthRequest = new SysPositionOrgAuthRequest();
            sysPositionOrgAuthRequest.setPositionId(positionId);
            sysPositionOrgAuthRequest.setDelFlag(Constants.DEL_FLAG_YES);
            sysPositionOrgAuthRequest.setUpdateDateStr(DateUtil.updateDateStr());
            sysPositionOrgAuthRequest.setUpdateBy(UserUtil.getUpdateByName());
            sysPositionOrgAuthRequest.setUpdateByNo(UserUtil.getUpdateByNo());
            sysPositionOrganizationAuthDao.updateByPositionId(sysPositionOrgAuthRequest);
            //新增数据授权
            //获取岗位详情
            SysPosition sysPositionTemp = sysPositionDao.selectByPrimaryKey(positionId);
            if (sysPositionTemp == null) {
                continue;
            }
            SysPositionOrganizationAuth sysPositionOrganizationAuthInsert = new SysPositionOrganizationAuth();
            sysPositionOrganizationAuthInsert.setId(ipKeyGenerator.getGenerateKey());
            sysPositionOrganizationAuthInsert.setPositionId(positionId);
            sysPositionOrganizationAuthInsert.setOrganizationId(sysPositionTemp.getOrganizationId());
            sysPositionOrganizationAuthInsert.setUpdateDateStr(DateUtil.updateDateStr());
            sysPositionOrganizationAuthInsert.setCreateBy(UserUtil.getCreateByName());
            sysPositionOrganizationAuthInsert.setUpdateBy(UserUtil.getUpdateByName());
            sysPositionOrganizationAuthInsert.setCreateByNo(UserUtil.getCreateByNo());
            sysPositionOrganizationAuthInsert.setUpdateByNo(UserUtil.getUpdateByNo());
            sysPositionOrganizationAuthDao.insertSelective(sysPositionOrganizationAuthInsert);
        }
        return jsonResult;
    }

}
